if editor is not None and source is editor.layout.explorer:
choice = quarkx.msgbox("You are about to create a new button from this group. Do you want the button to display a menu with the items in this group ?\n\nYES: you can pick up individual items when you click on this button.\nNO: you can insert the whole group in your map by clicking on this button.",
MT_CONFIRMATION, MB_YES_NO_CANCEL)
if choice == MR_CANCEL:
return
if choice == MR_YES:
list = [group2folder(list[0])]
if list[0].type=='.qtxfolder':
for item in list[0].subitems:
item["fixedscale"]="1"
else:
for item in list:
item["fixedscale"]="1"
UserDataPanel.drop(self, btnpanel, list, i, source)
def group2folder(group):
new = quarkx.newobj(group.shortname + '.qtxfolder')
for obj in group.subitems:
if obj.type == ':g':
obj = group2folder(obj)
else:
obj = obj.copy()
new.appenditem(obj)
return new
def degcycle(shear):
if shear > 180:
shear = shear-360
if shear < -180:
shear = shear+360
return shear
def undo_exchange(editor, old, new, msg):
undo = quarkx.action()
undo.exchange(old, new)
editor.ok(undo, msg)
def perptonormthru(source, dest, normthru):
"the line from source to dest that is perpendicular to (normalized) normthru"
diff = source-dest
dot = diff*normthru
return diff - dot*normthru
#
# Sets sign of vector so that its dot product is
# positive w.r.t. the axis it's most closely
# colinear with
#
def set_sign(vec):
gap = ind = 0
tuple = vec.tuple
for i in range(3):
if tuple[i]>gap:
gap = tuple[i]
ind = i
if gap < 0:
return -vec
else:
return vec
def ArbRotationMatrix(normal, angle):
# qhandles.UserRotationMatrix with an angle added
# normal: normal vector for the view plane
# texpdest: new position of the reference vector texp4
# texp4: reference vector (handle position minus rotation center)
# g1: if True, snap angle to grid
SNAP = 0.998
cosangle = math.cos(angle)
sinangle = math.sin(angle)
# oldcos = cosangle
# cosangle = cosangle*cosa-sinangle*sina
# sinangle = sinangle*cosa+sina*oldcos
m = quarkx.matrix((cosangle, sinangle, 0),
(-sinangle, cosangle, 0),
( 0, 0, 1))
v = orthogonalvect(normal, None)
base = quarkx.matrix(v, v^normal, -normal)
return base * m * (~base)
def squawk(text):
if quarkx.setupsubset(SS_MAP, "Options")["Developer"]:
quarkx.msgbox(text, MT_INFORMATION, MB_OK)
def findlabelled(list,label):
for item in list:
try:
if item.label==label:
return item
except (AttributeError):
pass
def cyclenext(i, len):
return (i+1)%len
def cycleprev(i, len):
return (i-1)%len
def projectpointtoplane(p,n1,o2,n2):
"project point to plane at o2 with normal n2 along normal n1"
v1 = o2-p
v2 = v1*n2
v3 = n1*n2
v4 = v2/v3
v5 = v4*n1
return p + v5
def matrix_u_v(u,v):
return quarkx.matrix((u.x, v.x, 0),
(u.y, v.y, 0),
(u.z, v.z, 1))
def intersectionPoint2d(p0, d0, p1, d1):
"intersection in 2D plane, point, direction"
for v in p0, d0, p1, d1:
if v.z != 0.0:
return None
det = d0.x*d1.y-d1.x*d0.y
if det==0.0:
return 0 # lines paralell
s = (p0.y*d1.x - p1.y*d1.x - d1.y*p0.x +d1.y*p1.x)/det
return p0+s*d0
#
# The two monstrosities below were derived from solving
# systems of equations in Maple V. The idea is to think
# of the texture plane as being a plane in a 3d texture
# space, so the texture space<->map space mappings are
# invertible. For the cases we're intererested in, the
# third texture coordinate is always zero, and drops out
# of the equations.
#
# Gets the s, t (texture) coordinates of a space point
# from the threepoints info and the point location(v)
s = (-c.z*d2.y*p0.x+c.z*p0.y*d2.x-c.z*d2.x*v.y+c.z*v.x*d2.y+d2.y*c.x*p0.z-d2.y*c.x*v.z-c.y*p0.z*d2.x+c.y*v.z*d2.x+c.y*d2.z*p0.x-c.y*d2.z*v.x+v.y*c.x*d2.z-p0.y*c.x*d2.z)/denom
t = -(-d1.x*c.y*p0.z+d1.x*c.y*v.z+d1.x*c.z*p0.y-d1.x*c.z*v.y-d1.z*c.x*p0.y+d1.z*c.x*v.y+c.x*p0.z*d1.y-c.x*v.z*d1.y-p0.x*c.z*d1.y+p0.x*c.y*d1.z+v.x*c.z*d1.y-v.x*c.y*d1.z)/denom